package cn.iocoder.yudao.framework.excel.core.strategy;

import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.*;

import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static cn.hutool.poi.excel.cell.CellUtil.getCellValue;

/**
 * 使用了注解  @ColumnWidth(30)的列就用注解的宽度，没有使用注解的列就使用默认的规则的长度，
 * 默认规则为根据表头的标题的长度为最小宽度，然后列的内容的长度的平均值为最大长度，这两个值间取中间值为列的默认规则，
 * @Author LiZhiMin
 * @Date 2024/8/23 10:35
 */

public class MixedColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {
    private final Map<Integer, Integer> columnWidthMap = new HashMap<>();

    public MixedColumnWidthStyleStrategy(Class<?> dataClass) {
        // 解析类中的字段，获取@ColumnWidth注解的列宽设置
        for (Field field : dataClass.getDeclaredFields()) {
            ColumnWidth columnWidth = field.getAnnotation(ColumnWidth.class);
            if (columnWidth != null) {
                int columnIndex = getColumnIndex(field); // 假设有方法获取列索引
                columnWidthMap.put(columnIndex, columnWidth.value());
            }
        }
    }

    @Override
    protected void setColumnWidth(CellWriteHandlerContext context) {
        Sheet sheet = context.getWriteSheetHolder().getSheet();
        int columnIndex = context.getColumnIndex();

        if (columnWidthMap.containsKey(columnIndex)) {
            // 使用@ColumnWidth注解的列宽
            int width = columnWidthMap.get(columnIndex);
            sheet.setColumnWidth(columnIndex, width * 200);
        } else {
            // 使用默认规则计算列宽
            int maxWidth = calculateColumnWidth(sheet, columnIndex);
            sheet.setColumnWidth(columnIndex, maxWidth * 200);
        }

        // 设置单元格内容居中
        setCellAlignment(sheet, columnIndex);
    }

    private int calculateColumnWidth(Sheet sheet, int columnIndex) {
        int totalLength = 0;
        int count = 0;
        int maxLength = 0;

        // 遍历所有数据行
        for (int rowIndex = 1; rowIndex < sheet.getPhysicalNumberOfRows(); rowIndex++) {
            Row row = sheet.getRow(rowIndex);
            if (row != null) {
                Cell cell = row.getCell(columnIndex, org.apache.poi.ss.usermodel.Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
                if (cell != null && cell.getCellType() == CellType.STRING) {
                    String cellValue = cell.getStringCellValue();
                    int length = cellValue.length();
                    totalLength += length;
                    count++;
                    if (length > maxLength) {
                        maxLength = length;
                    }
                }
            }
        }

        // 计算平均长度
        double averageLength = (count > 0) ? (double) totalLength / count : 0;

        // 计算中间值
        int averageLengthInt = (int) Math.round(averageLength);
        int averageMaxLength = (maxLength + averageLengthInt) / 2;

        // 设置列宽的最小值和最大值
        int defaultWidth = averageMaxLength + 15; // 添加额外空间
        return Math.min(defaultWidth, 250); // Excel的列宽最大值是255
    }

    // 假设有方法获取列的索引
    private int getColumnIndex(Field field) {
        // 实现获取列索引的逻辑
        return 0; // 这个方法需要根据实际情况进行实现
    }

    private void setCellAlignment(Sheet sheet, int columnIndex) {
        Workbook workbook = sheet.getWorkbook();

        // 创建并设置居中样式
        CellStyle centerStyle = workbook.createCellStyle();
        centerStyle.setAlignment(HorizontalAlignment.CENTER);
        centerStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        // 创建并设置标题样式
        CellStyle headerStyle = workbook.createCellStyle();
        Font headerFont = workbook.createFont();
        headerFont.setBold(true); // 加粗
        headerFont.setFontHeightInPoints((short) 15); // 字体大小
        headerStyle.setFont(headerFont);
        headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 背景色
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        headerStyle.setAlignment(HorizontalAlignment.CENTER);
        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);


        // 遍历所有行，应用居中样式
        for (Row row : sheet) {
            // 为第一行标题设置样式
            Row headerRow = sheet.getRow(0); // 第一行
            if (headerRow != null) {
                Cell headerCell = headerRow.getCell(columnIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                headerCell.setCellStyle(headerStyle);

            }

            Cell cell = row.getCell(columnIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);


            // 检查单元格内容类型并设置样式
            if (cell.getCellType() == CellType.STRING) {
                cell.setCellStyle(centerStyle);
            } else {
                // 对于 LocalDate 和 LocalDateTime 数据进行处理
                Object cellValue = getCellValue(cell); // 假设有方法获取单元格值
                if (cellValue instanceof LocalDate) {
                    LocalDate localDate = (LocalDate) cellValue;
                    cell.setCellValue(Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant())); // 转换为 Date
                    CellStyle dateStyle = workbook.createCellStyle();
                    dateStyle.setDataFormat(workbook.createDataFormat().getFormat("yyyy-mm-dd")); // 设置日期格式
                    cell.setCellStyle(dateStyle);
                } else if (cellValue instanceof LocalDateTime) {
                    LocalDateTime localDateTime = (LocalDateTime) cellValue;
                    cell.setCellValue(localDateTime); // 转换为 LocalDateTime
                }
            }
        }


    }


}